/*******************************************************************************
 * Copyright (c) 2002 Boris Pruessmann and others. All rights reserved. This
 * program and the accompanying materials are made available under the terms of
 * the Common Public License v0.5 which accompanies this distribution, and is
 * available at http://www.eclipse.org/legal/cpl-v05.html
 *
 * Contributors: Boris Pruessmann - Initial implementation.
 ******************************************************************************/
package net.sourceforge.perforce.ui.internal;

import com.google.common.collect.Lists;

import net.sourceforge.perforce.core.PerforceException;
import net.sourceforge.perforce.core.api.IOpenedResult;
import net.sourceforge.perforce.core.api.IPerforceServer;
import net.sourceforge.perforce.core.internal.P4TeamProvider;
import net.sourceforge.perforce.ui.IPerforceUIConstants;
import net.sourceforge.perforce.ui.PerforceUIPlugin;
import net.sourceforge.perforce.ui.dialogs.ConfirmationDialog;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.team.FileModificationValidationContext;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.team.core.RepositoryProvider;

import java.util.Iterator;
import java.util.List;

/**
 * @version $Revision: 493 $
 * @author <a href="mailto:bpruessmann@users.sourceforge.net">Boris
 *         Pruessmann</a>
 */
public class OtherOpenValidator extends AbstractOpenValidator {
  // -------------------------------------------------------------------------
  // Public Constructors

  /** Constructor for OtherOpenValidator. */
  public OtherOpenValidator() {
  }

  //----------------------------------------------------------------------------
  // -- Public Methods

  public IStatus validateEdit(IFile[] files, FileModificationValidationContext context) {
    IPreferenceStore store = PerforceUIPlugin.getPlugin().getPreferenceStore();
    if (!store.getBoolean(IPerforceUIConstants.PREF_WARN_ON_OTHER_OPEN)) {
      return new Status(IStatus.OK, PerforceUIPlugin.ID, IStatus.OK, "", null);
    }

    try {
      files = filesToCheckout(files);
      if (files.length > 0) {
        P4TeamProvider provider =
            (P4TeamProvider) RepositoryProvider.getProvider(files[0].getProject());

        IPerforceServer server = provider.getPerforceServer();
        String thisUser = server.getUser() + '@' + server.getClient();

        List<String> infoList = Lists.newArrayList();
        for (int i = 0; i < files.length; i++) {
          IOpenedResult[] openedResults = server.opened(files[i]);

          if (openedResults.length > 0) {
            List<String> users = Lists.newLinkedList();
            for (int j = 0; j < openedResults.length; j++) {
              String user = openedResults[j].getUserName() + '@' + openedResults[j].getClientName();
              if (!user.equals(thisUser)) {
                users.add(user);
              }
            }

            if (users.size() > 0) {
              StringBuilder buffer = new StringBuilder(files[i].getName());
              buffer.append("is also opened by ");
              for (Iterator<String> it = users.iterator(); it.hasNext();) {
                String user = it.next();
                buffer.append(user);
                if (it.hasNext()) {
                  buffer.append(", ");
                }
              }

              infoList.add(buffer.toString());
            }
          }
        }

        if (infoList.size() > 0) {
          String message =
              "One or more files that are going to be opened for edit are also "
                  + "opened by other users. Do you want to continue anyway?";

          String[] infos = infoList.toArray(new String[infoList.size()]);
          boolean shouldContinue =
              ConfirmationDialog.openConfirmation((Shell) context.getShell(), "Open for Edit", message, infos);

          if (!shouldContinue) {
            return new Status(IStatus.ERROR, PerforceUIPlugin.ID, IStatus.ERROR,
                "The user refused to open the file for edit.", null);
          }
        }
      }

      return new Status(IStatus.OK, PerforceUIPlugin.ID, IStatus.OK, "", null);
    } catch (PerforceException e) {
      return e.getStatus();
    }
  }
}
